package com.dodo.blog.server;

import com.dodo.blog.exception.UserAlreadyRated;
import com.dodo.blog.model.Article;
import com.dodo.blog.request.ArticlesRequest;

import java.util.List;

/**
 * @author <a href="mailto:pohorelec@comvai.com">Jozef Pohorelec</a>
 */
public interface ArticleService
{
    /**
     * Save acount to datastore
     *
     * @param article {@link com.dodo.blog.model.Article} entity to save
     */
    void saveArticle( Article article );

    /**
     * Get article by articleId
     *
     * @param articleId of {@link com.dodo.blog.model.Article}
     * @return {@link Article}
     */
    Article getArticleById( Long articleId );

    /**
     * Return list of articles by specified request
     *
     * @param request {@link ArticlesRequest}
     * @return list of {@link Article}
     */
    List<Article> getArticles( ArticlesRequest request );

    /**
     * Return most viewed articles
     *
     * @return list of most viewed articles
     */
    List<Article> getMostViewedArticles();

    /**
     * Return best rated articles
     *
     * @return list of best rated articles
     */
    List<Article> getBestRatedArticles();

    /**
     * Return recently published articles
     *
     * @return list of recently published articles
     */
    List<Article> getRecentArticles();

    /**
     * Delete {@link Article} from datastore
     *
     * @param articleId id of {@link Article}
     */
    void deleteArticle( Long articleId );

    /**
     * Rate article by specified id with rate value
     *
     * @param articleId id of {@link Article}
     * @param accountId id of {@link com.dodo.blog.model.Account}
     * @param rate      rate article
     * @return {@link Article}
     * @throws com.dodo.blog.exception.UserAlreadyRated
     *          if user already rated article
     */
    Article rate( Long articleId, Long accountId, Long rate ) throws UserAlreadyRated;

    /**
     * Return <code>true</code> if user already voted for article, <code>>false</code> otherwise
     *
     * @param articleId id of {@link Article}
     * @param accountId id of {@link com.dodo.blog.model.Account}
     * @return <code>true</code> if user already voted for article, <code>>false</code> otherwise
     */
    boolean isArticleRated( Long articleId, Long accountId );

    /**
     * Publish article
     *
     * @param articleId id of {@link Article}
     */
    void publishArticle( Long articleId );

    /**
     * Hide article
     *
     * @param articleId {@link Article}
     */
    void hideArticle( Long articleId );
}